package com.tianlan.blog.service.impl;

import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.tianlan.blog.dao.SysRoleDao;
import com.tianlan.blog.dao.SysRoleResourceDao;
import com.tianlan.blog.dao.SysUserRoleDao;
import com.tianlan.blog.entity.SysRole;
import com.tianlan.blog.service.SysRoleService;
import com.tianlan.common.base.BusinessException;
import com.tianlan.common.page.MyPage;

@Service
public class SysRoleServiceImpl implements SysRoleService {

	@Autowired
	private SysRoleDao sysRoleDao;

	@Autowired
	private SysUserRoleDao sysUserRoleDao;

	@Autowired
	private SysRoleResourceDao sysRoleResourceDao;

	@Override
	public List<SysRole> selectSysRoleList(SysRole role,MyPage<SysRole> page) {
		return sysRoleDao.selectSysRoleList(role,page);
	}

	@Override
	public int selectSysRoleCount(SysRole role) {
		return sysRoleDao.selectSysRoleCount(role);
	}
	
	@Override
	public List<SysRole> getSysRoleList(List<Integer> roleIds) {
		return sysRoleDao.getSysRoleList(roleIds);
	}

	@Override
	public List<SysRole> getSysRole() {
		return sysRoleDao.findAll();
	}
	
	@Override
	public boolean createRole(SysRole role) {
		int isRole = sysRoleDao.isSysRole(role.getRoleName(), role.getRoleKey());
		if (isRole != 0) {
			throw new BusinessException("角色名称或角色标识已经存在");
		}
		SysRole roleSave = sysRoleDao.saveAndFlush(role);
		if (roleSave != null && !"".equals(roleSave)) {
			return true;
		} else {
			return false;
		}
	}

	@Override
	@CacheEvict(value = "roles", allEntries = true)
	public boolean updateRole(SysRole role) {
		if (sysRoleDao.isRoleById(role.getId()) == 0) {
			throw new BusinessException("角色标识不存在");
		} else {
			SysRole roleSave = sysRoleDao.saveAndFlush(role);
			return (roleSave != null && !"".equals(roleSave));
		}
	}

	@Override
	public boolean updateRoleById(Integer id, String roleStatus) {
		return sysRoleDao.updateRoleById(id, roleStatus) != 0;
	}

	@Override
	@CacheEvict(value = "roles", allEntries = true)
	public boolean deleteRole(Integer roleId) {
		int isRole = sysRoleDao.deleteRoleById(roleId);
		if (isRole != 0 && sysUserRoleDao.isUserRoleByRoleId(roleId) != 0) {
			// 删除用户和角色的关联关系
			sysUserRoleDao.deleteUserRoleByRoleId(roleId);
		}
		if (isRole != 0 && sysRoleResourceDao.isRoleResourceByRoleId(roleId) != 0) {
			// 删除角色和权限的关联关系
			sysRoleResourceDao.deleteRoleResourceByRoleId(roleId);
		}
		return isRole != 0;
	}

	@Override
	public long checkRoleName(SysRole role) {
		@SuppressWarnings("serial")
		Specification<SysRole> specification = new Specification<SysRole>() {
			@Override
			public Predicate toPredicate(Root<SysRole> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				String roleName = role.getRoleName();
				Predicate roleNamePredicate = cb.equal(root.get("roleName"), roleName);
				Predicate delFlagPredicate = cb.equal(root.get("delFlag"), "0");
				if (null != role.getId()) {
					Predicate roleIdPredicate = cb.notEqual(root.get("id"), role.getId());
					return cb.and(roleNamePredicate, roleIdPredicate, delFlagPredicate);
				}
				return cb.and(roleNamePredicate,delFlagPredicate);
			}
		};
		return sysRoleDao.count(specification);
	}
	@Override
	public long checkRoleKey(SysRole role) {
		@SuppressWarnings("serial")
		Specification<SysRole> specification = new Specification<SysRole>() {
			@Override
			public Predicate toPredicate(Root<SysRole> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				String roleKey = role.getRoleKey();
				Predicate roleNamePredicate = cb.equal(root.get("roleKey"), roleKey);
				Predicate delFlagPredicate = cb.equal(root.get("delFlag"), "0");
				if (null != role.getId()) {
					Predicate roleIdPredicate = cb.notEqual(root.get("id"), role.getId());
					return cb.and(roleNamePredicate, roleIdPredicate, delFlagPredicate);
				}
				return cb.and(roleNamePredicate, delFlagPredicate);
			}
		};
		return sysRoleDao.count(specification);
	}
}
